/*
 * WorkflowQueue.java
 *
 * Created on Jun 5, 2007, 11:56:04 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package com.infomancers.workflow;

import java.util.Queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author freakazoid
 */
public class WorkflowQueue {
    private class WorkflowPlaceListener implements PlaceListener {
        public void tokenAdded(Place place, Token token) {
            try {
                assert place == workflow.getOutput() : "Place is not output place";
                tokenQueue.put(token);
            } catch (InterruptedException ex) {
                Logger.getLogger("global").log(Level.SEVERE, "Failed to put token into queue", ex);
            }
        }
        
        public void tokenRemoved(Place place, Token token) { }
    }
    
    private BlockingQueue<Token> tokenQueue = new LinkedBlockingQueue<Token>();
    
    
    private Workflow workflow;
    
    public WorkflowQueue(Workflow workflow) {
        this.workflow = workflow;
        
        Place output = this.workflow.getOutput();
        if (output != null) {
            output.addPlaceListener(new WorkflowPlaceListener());
        }
    }
    
    public final void pushData(Object data) {
        workflow.getFlowManager().send(new Token(data), workflow.getInput());
    }
    
    public final Object pullData() {
        try {
            return tokenQueue.take().getData();
        } catch (InterruptedException ex) {
            Logger.getLogger("global").log(Level.SEVERE, "Failed to retrieve data from queue", ex);
            return null;
        }
    }
    
    public boolean hasData() {
        return tokenQueue.size() != 0;
    }
}
